import { THREE } from '@amcax/web-render';
import { getPointByVecLen, getScreenNormal } from '../utils';
import { KeepSizeObject3D } from './KeepSizeObject3D';
import { CSMesh } from './CSMesh';
type ArrowAttrs = {
  vec?: THREE.Vector3;
  arrowEnd?: THREE.Vector3;
  center?: THREE.Vector3;
  sign?: 1 | -1;
  camera?: THREE.PerspectiveCamera | THREE.OrthographicCamera;
};
const { BufferGeometry, MeshBasicMaterial, DoubleSide } = THREE;
const origin = new THREE.Vector3(0, 0, 0);
/**
 * @description 参数化的箭头
 * */
export class Arrow {
  vec: THREE.Vector3;
  arrowEnd: THREE.Vector3;
  center: THREE.Vector3;
  arrowMesh: CSMesh;
  keepSizeGroup: KeepSizeObject3D;
  scene: THREE.Object3D;
  position: THREE.Vector3;
  constructor(attrs: ArrowAttrs) {
    this.createArrow(attrs);
    this.keepSizeGroup = new KeepSizeObject3D(attrs.camera);
    this.keepSizeGroup.renderOrder = 1000;
  }
  // 获取箭头的三角形面片
  getArrowPoint({ vec, arrowEnd, sign = -1, camera }: ArrowAttrs) {
    arrowEnd && (this.position = arrowEnd);
    // 设置箭头头部参数
    const arrowLen = 2; // 箭头总长度
    //旋转轴
    const axis = getScreenNormal(camera);
    const startP = getPointByVecLen(vec, (sign * -arrowLen) / 3, origin); // 箭杆尾部中心点
    const endP = getPointByVecLen(vec, (sign * -arrowLen) / 1.7, origin); // 箭杆和箭头链接部分的中心点
    // vec 向量旋转90deg
    const vec2 = vec.clone().applyAxisAngle(axis, Math.PI / 2);
    const v1 = getPointByVecLen(vec2, arrowLen / 1.5, endP); // 箭头头部上点
    const v2 = getPointByVecLen(vec2, -arrowLen / 1.5, endP); // 箭头头部下点
    const v3 = getPointByVecLen(vec, (sign * -arrowLen) / 2, endP); // 箭头顶点

    const r1 = getPointByVecLen(vec2, arrowLen / 3, endP); // 箭头和箭头链接部分的上点
    const r2 = getPointByVecLen(vec2, -arrowLen / 3, endP); // 箭头和箭头链接部分的下点
    const r3 = getPointByVecLen(vec2, arrowLen / 3, startP); // 箭杆上点
    const r4 = getPointByVecLen(vec2, -arrowLen / 3, startP); // 箭杆下点
    return [v3, v1, r1, r1, r3, r2, r3, r4, r2, r2, v2, v3, v3, r1, r2]; // 三个一组，组成三角形面片 笔记：62
  }
  // 创建箭头
  createArrow(attrs: ArrowAttrs) {
    const vertices = this.getArrowPoint(attrs);
    const geometry = new BufferGeometry();
    geometry.setFromPoints(vertices);
    const material = new MeshBasicMaterial({
      side: DoubleSide,
      depthTest: false, // 不进行深度测试
      color: '#00ff00',
    });
    this.arrowMesh = new CSMesh({
      geometry,
      material,
      modelDxid: 'divMesh',
    });
    this.arrowMesh.setRenderOrder(1000);
    this.arrowMesh.visible = true;
  }
  // 更新箭头
  update(attrs: ArrowAttrs) {
    const vertices = this.getArrowPoint(attrs);
    this.arrowMesh.geometry.setFromPoints(vertices);
    this.setPosition();
  }
  // 添加到场景
  addTo(scene) {
    this.scene = scene;
    this.arrowMesh.addTo(this.keepSizeGroup);
    scene.add(this.keepSizeGroup);
    this.setPosition();
  }
  //
  setPosition() {
    if (this.position) {
      this.keepSizeGroup.position.copy(this.position);
    }
  }
  // 销毁
  destroy() {
    this.scene.remove(this.keepSizeGroup);
    this.arrowMesh?.destroy();
    this.keepSizeGroup.clear();
    this.arrowMesh = null;
  }
}
